home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
diskutil
/
noahdi.zoo
/
noahdi
/
hd_extra.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-24
|
14KB
|
377 lines
/*
File: HD_EXTRA.C Extra Low Level Harddisk Routines.
*/
/*
Copyright (c) 1988 - 1991 by Ted Schipper.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
This software is provided AS IS with no warranties of any kind. The author
shall have no liability with respect to the infringement of copyrights,
trade secrets or any patents by this file or any part thereof. In no
event will the author be liable for any lost revenue or profits or
other special, indirect and consequential damages.
*/
#include "dma.h"
#include "mfp.h"
#include "hddriver.h"
#include "system.h"
/***************************************************************************
Some EXTRA LOW-LEVEL Stuff
----------------------------
HISTORY
---------
Nov 1988. THS. Started. Tested send_cmd routine. Added req_sense.
Dec 1988. THS. Tested req_sense routine. Not sure it works OK. HAC bug.
Jan 1989. THS. Added, tested wd_msel and wd_format. Also tested some
drive errors. Controller always reports no errors.
V0.00
***************************************************************************/
/***************************************************************************
*
* Function name : wd_format. Format hard disk
* Parameters : short device number. 4 bits: bit 0 = drive # ( 0 or 1)
* bit 1-3 = controller # (0-7)
* short pattern_flag. 2 bits: bit 1-3 = Data pattern Flag
* short pattern. 8 bits: bit 0-7 = Data pattern
* short ileave_high. 8 bits: bit 0-7 = Interleave High
* short ileave_low. 8 bits: bit 0-7 = Interleave Low
* Returns : long. dma completion byte or time-out (-1)
* Description : Format a harddisk with given pattern and interleave.
* Comments : Assumes processor is in supervisor mode, and drive
* specifications has been set with the wd_msel command.
*/
long wd_format(dev,pattern_flag,pattern,ileave_high,ileave_low)
short dev;
short pattern_flag;
short pattern;
short ileave_high;
short ileave_low;
{
long status;
short dummy = 0;
FLOCK = -1; /* disable FDC operations */
DMA->MODE = NO_DMA | HDC; /* write 1st byte (0) with A1 low */
DMA->DATA = (short)((dev >> 1) << 5) | (HD_FD); /* contrl# + command */
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = (short)((dev & 1) << 5) | (pattern_flag & 6); /* drv# + pat flag */
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = pattern;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = ileave_high;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = ileave_low;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = dummy;
DMA->MODE = NO_DMA | HDC | A0;
while ((MFP->GPIP & IO_DINT) == IO_DINT) ; /* wait (forever) for completion */
status = (long)(DMA->DATA & 0x00FF); /* get the status */
hdone(); /* restore DMA device to normal */
return(status); /* return completion status */
}
/***************************************************************************
*
* Function name : wd_msel. Mode select. Specify drive format parameters.
* Parameters : short device number. 4 bits: bit 0 = drive # ( 0 or 1 )
* bit 1-3 = controller # (0-7)
* short count. size of parameter block.
* char * parameterblock. pointer to parameter block.
* Returns : long. ASCI completion byte or time-out.
* Description : Send a mode select command to a controller and drive
* followed by the parameter block which is send under DMA.
* Comments : Assumes processor is in supervisor mode, and parameter
* block is not bigger than 1 sector (512 bytes).
*/
long wd_msel(dev,cnt,param)
short dev;
short cnt;
char * param;
{
long status;
short dummy = 0;
FLOCK = -1; /* disable FDC operations */
setdma(param); /* setup DMA transfer address */
DMA->MODE = NO_DMA | HDC; /* write 1st byte (0) with A1 low */
DMA->DATA = (short)((dev >> 1) << 5) | (HD_MSEL); /* contrl# + command */
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = (short)((dev & 1) << 5); /* drv# */
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = dummy;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = dummy;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->DATA = cnt;
DMA->MODE = NO_DMA | HDC | A0;
if (qdone() != OK) /* wait for ack */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->MODE = NO_DMA | SC_REG; /* clear FIFO and */
DMA->MODE = DMA_WR | NO_DMA | SC_REG; /* select sector count register */
DMA->SECT_CNT = 1; /* sector count */
DMA->MODE = DMA_WR | NO_DMA | HDC | A0; /* select DMA register again */
DMA->DATA = dummy; /* write last byte */
DMA->MODE = DMA_WR; /* start DMA transfer */
if (fdone() != OK) /* wait for DMA completion */
{
hdone(); /* restore DMA device to normal */
return(ERROR);
}
DMA->MODE = DMA_WR | NO_DMA | HDC | A0; /* set DMA register to normal */
status = (long)(DMA->DATA & 0x00FF); /* get ASCI completion byte */
hdone(); /* restore DMA device to normal */
return(status); /* return ASCI completion byte */
}
/***************************************************************************
*
* Function name : dosahdxc. Send an ASCI command with timeout.
* Parameters : short device number. 4 bits: bit 0 = drive # ( 0 or 1 )
* bit 1-3 = controller # (0-7)
* : short * cdb. Pointer to the Command Descriptor Block.
* Returns : long OK = command block send OK.
* ERROR = timeout.
* Description : Send 6 bytes from the Command Descriptor Block to an
* ASCI device.
* Comments : Assumes processor is in supervisor mode.
*/
long dodahdxc(dev,cdb)
short dev;
short cdb[6];
{
short i;
long status;
cdb[0] |= ((dev >> 1) << 5); /* put controller# in first byte */
cdb[1] |= ((dev & 1) << 5); /* put drive# in second byte */
FLOCK = -1; /* disable FDC operations */
DMA->